<template>
  <!-- vue项目双滑块组件 -->
  <div
    :style="{
      display: 'flex',
      'justify-content': 'center',
      width: '100%',
    }"
  >
    <div
      id="slider-box"
      class="slider-box"
      :style="{
        width: '100%',
        background: outBg,
      }"
      @mousedown="handleClickZong"
    >
      <div
        :class="['slider-nei', isClick ? 'transtion' : '']"
        :style="{
          width: Math.abs(moveDistanceOne - moveDistanceTwo) + 20 + 'px',
          transform:
            moveDistanceTwo > moveDistanceOne
              ? `translateX(${moveDistanceOne}px)`
              : `translateX(${moveDistanceTwo}px)`,
          background: neiBg,
        }"
      />
      <div
        v-if="!range"
        :style="{
          transform: `translateX(${moveDistance}px)`,
        }"
        :class="{
          'point-box': true,
          zhua: isMove,
          transtion: isClick,
        }"
        @mousedown.stop.prevent="handleMousedown"
      />
      <div
        v-if="range"
        :style="{
          transform: `translateX(${moveDistanceOne}px)`,
          background: btnBg,position:'absolute','z-index': leftIndex
        }"
        :class="{
          'point-box': true,
          zhua: isMove,
          transtion: isClick,
        }"
        @mousedown.stop.prevent="handleMousedownOne"
        @touchstart="handleMousedownOne1"
        @mouseup="handleUp"
        @touchend="handleUp"
      >
        {{ Math.trunc(moveDistanceOne * rate) + min }}
      </div>
      <div
        :style="{
          transform: `translateX(${moveDistanceTwo}px)`,
          background: btnBg,position:'absolute','z-index': rightIndex
        }"
        :class="{
          'point-box': true,
          point: true,
          zhua: isMove,
          transtion: isClick,
        }"
        @mousedown.stop.prevent="handleMousedownTwo"
        @touchstart="handleMousedownTwo1"
        @mouseup="handleUp"
        @touchend="handleUp"
      >
        {{ Math.trunc(moveDistanceTwo * rate + min) }}
      </div>
    </div>
  </div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
  data() {
    return {
      range: true, // 是否开启双滑块
      isClick: false, // 是否直接点击
      isMove: false, // 是否处于滑动状态
      flag: false, //
      moveDistance: 0,
      initX: 0, // 记录鼠标点下时的坐标，用于移动中求差值
      moveStart: 0, // 进度条的开始位置
      moveEnd: 0, // 进度条的结束位置
      moveDistanceOne: 0, // 滑块一的位置
      moveDistanceTwo: 50, // 滑块二的位置
      rate: 1, // 比率
      outerWidth: 100,
      rate1: 1, // 比率
      outerWidth1: 100,
      valueRange: [],
      leftIndex: 0,
      rightIndex: 0.5
    }
  },
  computed: {
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters('common', [
      'userType'
    ])
  },
  props: {
    // 可选择范围的较大值
    max: {
      type: Number,
      default: 750
    },
    // 外层背景色
    outBg: {
      type: String,
      default: '#F0F0F0'
    },
    // 滑块背景色
    btnBg: {
      type: String,
      default: '#497cfe'
    },
    // 内层背景色
    neiBg: {
      type: String,
      default: '#E5EDFF'
    },
    // 可选择范围的较小值
    min: {
      type: Number,
      default: 150
    },
    // 已经选择的范围
    valuesRange: {
      type: Array,
      default: [350, 550]
    }
  },
  watch: {
    valuesRange: {
      handler(val1) {
        this.valueRange = val1
        this.init()
      },
      deep: true,
      immediate: true
    }
  },
  mounted() {
    window.addEventListener('resize', this.init)
    window.addEventListener('mouseup', () => {
      if (this.flag) {
        this.handleUp2()
        this.flag = false
      }
    })
    // this.init();
  },
  methods: {
    init() {
      this.$nextTick(() => {
        /* this.valueRange [1, 750] */
        if (this.valueRange && this.valueRange.length > 0) {
          const max_min = this.max - this.min
          var slide_width = document.querySelector('#slider-box').clientWidth
          var point_width = document.querySelector('.point').clientWidth
          this.outerWidth = slide_width - point_width
          this.outerWidth1 = slide_width - point_width - point_width
          this.rate = max_min / this.outerWidth
          this.rate1 = max_min / this.outerWidth1
          const vr = JSON.parse(JSON.stringify(this.valueRange))
          if (vr[0] > vr[1]) {
            this.valueRange = [vr[1], vr[0]]
          }
          this.moveDistanceOne = (this.valueRange[0] - this.min) / this.rate
          this.moveDistanceTwo = (this.valueRange[1] - this.min) / this.rate
          this.$forceUpdate()
        }
      })
    },
    // 移动端 touchstart 点击监听 ontouchmove 移动监听 ontouchend 松开监听，e.changedTouches[0] 元素偏移的一些数据
    // PC端 mousedown 点击监听 onmousemove 移动监听 onmouseup 松开监听
    /**
     * 初始坐标就是鼠标点下时的clientX坐标，这样就可以做到将slider放在页面任何位置，拖动原点偏移的量也是正确的，
     * 因为原点移动距离是用鼠标移动的位置和鼠标点下的位置做差值计算，所以不用担心这里的clientX会因为slider放在
     * 别的地方而导致距离计算错误
     * @param e
     */
    // 鼠标点击
    handleMousedown(e) {
      this.isMove = true
      this.initX = e.clientX
      const sliderDomWidth = this.outerWidth
      // const sliderDomWidth = document.getElementsByClassName("slider-box")[0].clientWidth;
      document.onmousemove = (e) => {
        if (this.isMove) {
          this.moveDistance += e.clientX - this.initX
          this.initX = e.clientX
          if ((this.moveDistance / sliderDomWidth) * 100 > 100) {
            this.moveDistance = sliderDomWidth
            return
          }
          if ((this.moveDistance / sliderDomWidth) * 100 < 0) {
            this.moveDistance = 0
            return
          }
        }
      }
      document.onmouseup = (e) => {
        this.isMove = false
        document.onmousemove = null
      }
    },
    handleUp() {
      // console.log('this.valueRange', this.valueRange);
      // this.$emit("recommendRange", this.valueRange);
    },
    handleUp2() {
      this.$emit('recommendRange', this.valueRange)
    },
    handleUp3() {
      this.$emit('recommendRange', this.valueRange)
    },
    handleUp4() {
      this.$emit('recommendRange', this.valueRange)
    },
    /**
     * 当点击进度条某一个位置时，快捷设置进度条的位置，这里就需要用offsetX而不是clientX了。这里需要设置的便宜距离是鼠标距离目标元素的距离而不是鼠标在整个页面上的坐标
     * @param e
     */
    handleClickZong(e) {
      this.isClick = true
      setTimeout(() => {
        this.isClick = false
      }, 300)
      this.moveDistance = e.offsetX - 10
    },
    // 滑动滑块1
    handleMousedownOne1(e) {
      if (this.userType != 'VIP') {
        this.$store.commit('common/SET_SHOWEXCHANGEVIP', true)
        return
      }
      this.flag = true
      this.isMove = true
      this.leftIndex = 0.5
      this.rightIndex = 0
      let currentDistance = e.changedTouches[0].clientX
      document.ontouchmove = (e) => {
        const item = e.changedTouches[0]
        if (this.isMove) {
          const moveX = item.clientX - currentDistance
          currentDistance = item.clientX
          this.moveDistanceOne += moveX
          if (this.moveDistanceOne < 0) {
            this.moveDistanceOne = 0
            return
          }
          if (this.moveDistanceOne > this.moveDistanceTwo) {
            this.moveDistanceOne = this.moveDistanceTwo
            return
          }
          this.valueRange = [this.moveDistanceOne, this.moveDistanceTwo]
        }
      }
      document.ontouchend = (e) => {
        this.isMove = false
        // this.flag = false;
        document.onmousemove = null
      }
    },
    handleMousedownOne(e) {
      console.log(e)
      if (this.userType != 'VIP') {
        this.$store.commit('common/SET_SHOWEXCHANGEVIP', true)
        return
      }
      this.flag = true
      this.isMove = true
      this.leftIndex = 0.5
      this.rightIndex = 0
      let currentDistance = e.clientX
      document.onmousemove = (e) => {
        if (this.isMove) {
          /* moveX 滑块横向移动的距离 */
          const moveX = e.clientX - currentDistance
          currentDistance = e.clientX
          this.moveDistanceOne += moveX
          if (this.moveDistanceOne < 0) {
            this.moveDistanceOne = 0
            return
          }
          if (this.moveDistanceOne > this.moveDistanceTwo) {
            this.moveDistanceOne = this.moveDistanceTwo
            return
          }

          const arr_one = Math.trunc(this.moveDistanceOne * this.rate) + this.min
          const arr_two = Math.trunc(this.moveDistanceTwo * this.rate) + this.min
          this.valueRange = [arr_one, arr_two]
        }
      }
      document.onmouseup = (e) => {
        this.isMove = false
        // this.flag = false;
        document.onmousemove = null
      }
    },
    // 滑动滑块2
    handleMousedownTwo1(e) {
      if (this.userType != 'VIP') {
        this.$store.commit('common/SET_SHOWEXCHANGEVIP', true)
        return
      }
      this.isMove = true
      this.flag = true
      this.leftIndex = 0
      this.rightIndex = 0.5
      let currentDistance = e.changedTouches[0].clientX
      document.ontouchmove = (e) => {
        if (this.isMove) {
          const item = e.changedTouches[0]
          const moveX = item.clientX - currentDistance
          currentDistance = item.clientX
          this.moveDistanceTwo += moveX
          if (this.moveDistanceTwo > this.outerWidth) {
            this.moveDistanceTwo = this.outerWidth
            return
          }
          if (this.moveDistanceTwo < this.moveDistanceOne) {
            this.moveDistanceTwo = this.moveDistanceOne
            return
          }
          if (this.moveDistanceTwo < 0) {
            this.moveDistanceTwo = 0
            return
          }
          this.valueRange = [this.moveDistanceOne, this.moveDistanceTwo]
        }
      }
      document.ontouchend = (e) => {
        this.isMove = false
        // this.flag = false;
        document.onmousemove = null
      }
    },
    // 滑动滑块2
    handleMousedownTwo(e) {
      if (this.userType != 'VIP') {
        this.$store.commit('common/SET_SHOWEXCHANGEVIP', true)
        return
      }
      this.flag = true
      this.isMove = true
      this.leftIndex = 0
      this.rightIndex = 0.5
      let currentDistance = e.clientX
      document.onmousemove = (e) => {
        if (this.isMove) {
          const moveX = e.clientX - currentDistance
          currentDistance = e.clientX
          this.moveDistanceTwo += moveX
          if (this.moveDistanceTwo > this.outerWidth) {
            this.moveDistanceTwo = this.outerWidth
            return
          }
          if (this.moveDistanceTwo < this.moveDistanceOne) {
            this.moveDistanceTwo = this.moveDistanceOne
            return
          }
          if (this.moveDistanceTwo < 0) {
            this.moveDistanceTwo = 0
            return
          }
          const arr_one = Math.trunc(this.moveDistanceOne * this.rate) + this.min
          const arr_two = Math.trunc(this.moveDistanceTwo * this.rate) + this.min
          this.valueRange = [arr_one, arr_two]
        }
      }
      document.onmouseup = (e) => {
        this.isMove = false
        // this.flag = false;
        document.onmousemove = null
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@function autoPx($num) {
  @return (($num / 1200) * 24rem);
}
.slider-box {
  height: autoPx(10);
  border-radius: autoPx(20);
  position: relative;
}

.slider-nei {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: autoPx(10);
  border-radius: autoPx(20);
}

.point-box {
  width: autoPx(43);
  height: autoPx(20);
  border-radius: autoPx(20);
  position: absolute;
  top: -(autoPx(5));
  color: #fff;
  font-size: autoPx(12);
  line-height: autoPx(20);
  text-align: center;
  user-select: none;
  cursor: pointer;
}

.point-box:hover {
  cursor: grab;
}

.zhua:active {
  cursor: grabbing;
}

.transtion {
  transition: all 0.3s;
}
</style>
